home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Snapshot.c
-
- Contains: This application demonstrates how to quickly and
- efficiently capture the main device's desktop into
- a window. The program basically reads the image
- stored in the the main device's pixmap then copies
- it to a custom pixmap. The custom pixmap is de-
- fined at the same depth of the main device and
- contains an identical copy of that device's color-
- table. This is done to provide the fastest
- performance possible when copying from an offscreen
- to onscreen pixmap. By making sure the pixel values
- map to the exact same colors in both colortables,
- copybits will do a direct transfer of bits without
- wasting time remapping the colors. Also the ctSeed
- field for each colortable should be the same. Finally,
- since the main device's bounding rect is different
- than that of the offscreen's, the copying performance
- for the device to the offscreen is slightly affected
- because of the scaling required. However, the copying
- performance for the offscreen to the window is the
- best possible since the bounding rects for each are
- identical.
-
- Written by: EL
-
- Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 08/2000 JM Major revisions made. In addition to being "carbonized"
- added: multiple windows, refreshing, saving, conditional
- menu bar for OS X and 9, Apple Event Quit support,
- updated about box....(bunch of extra things)
- 11/6/1999 GGS Updated to work with modern (1999) Mac OS.
- Fixed a PixMap disposing bug. Updated casts
- and headers.
- 7/14/1999 KG Updated for Metrowerks Codewarror Pro 2.1
- */
-
- #include "Snapshot.h"
- #include <PLStringFuncs.h>
-
- // Different picture scaling constants
- const int FULL_SIZE = 1;
- const float HALF_SIZE = 1.41; // square root of 2, roughly
- const int QUARTER_SIZE = 2;
-
- /* Global Variable Definitions */
-
- Rect gBounds; // System resolution, effectively
- Boolean gDone = false; // Application termination global
- Boolean gDoingTrick = false; // "Trick" flag
- float gScale = QUARTER_SIZE; // Scaling the window, relative to resolution (default of 1/2 width and height)
- Rect gMinWindowSize; // The minimum window size
- const unsigned char* fileName = "\pDesktop Pic"; // Generic filename
- const unsigned char* defaultName = "\pSnapshot"; // Default Save File Name
- unsigned long resizingDelay = 0;
-
- void main()
- {
- initMac();
- setUp();
-
- doNewSnapshot();
- adjustMenus();
- doEventLoop();
- destroyAllWindows();
- }
-
- // Tests to see if we are running on Mac OS X.
- Boolean onOSX()
- {
- long response;
- OSErr anErr = noErr;
-
- anErr = Gestalt(gestaltSystemVersion, &response);
-
- return response >= 0x01000 && (anErr == noErr);
- }
-
- void destroyAllWindows()
- {
- WindowPtr theWindow = FrontWindow();
- while(FrontWindow() != NULL) {
- disposeWindow(theWindow);
- theWindow = FrontWindow();
- }
- }
-
- void initMac()
- {
- // the only "init" calls needed in carbon
- InitCursor();
- FlushEvents( 0, everyEvent );
- }
-
- void setUp()
- {
- Handle menuBar;
- OSErr anErr = noErr;
- long response;
-
- // Carbon Porting guidelines say provide alternate menu bar/menu scheme for OS X
- // This is just one way of doing a different menu for 9 and X, which is pretty static
- if (onOSX())
- menuBar = GetNewMBar(MENU_BAR_IDX); //if we are running on X, need menu without a File->Quit
- else
- menuBar = GetNewMBar(MENU_BAR_ID); //default menu bar
-
- anErr = ResError();
-
- if ( menuBar == nil || anErr != noErr )
- ExitToShell();
-
- SetMenuBar(menuBar);
- DisposeHandle(menuBar);
-
- DrawMenuBar();
- // Install 'quit' event handler
- // This "handler" is called when a user selects Application->Quit on OS X.
- if ((Gestalt(gestaltAppleEventsAttr, &response) == noErr)) {
- anErr = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
- NewAEEventHandlerUPP(AEQuitHandler), 0, false);
- if (anErr != noErr)
- ExitToShell();
- }
- }
-
- void doNewSnapshot()
- {
- WindowPtr newWindow = nil;
- PixMapHandle pixHandle = nil;
- // Snapshots consist of a window and a PixMap, could have chosen
- // to use only pictures instead, but the existing code dealt with
- // PixMaps, so I kept the existing "concept"
-
- pixHandle = createScreenPixMap();
- newWindow = createWindow();
- // Window's refCon is its handle to a PixMap
- SetWRefCon(newWindow, (long)pixHandle);
- drawImage( newWindow );
- ShowWindow( newWindow );
- }
-
- WindowPtr createWindow()
- {
- Rect wBounds;
- BitMap bitMap;
- int top, left, width, height;
- WindowPtr newWindow;
-
- // Centering the window is a good thing....
-
- GetQDGlobalsScreenBits(&bitMap);
-
- width = ((bitMap.bounds.right - bitMap.bounds.left) / gScale);
- height = ((bitMap.bounds.bottom - bitMap.bounds.top) / gScale);
-
- left = (((bitMap.bounds.right - bitMap.bounds.left) - width) / 2);
- top = (((bitMap.bounds.bottom - bitMap.bounds.top) - height) / 2);
-
- // if scale is same size or bigger than the screen
- if (gScale <= FULL_SIZE)
- top = left = GetMBarHeight() * 3; //arbitrary position....
-
- // Create a window to display the final offscreen image.
- SetRect( &wBounds, left, top, left + width, top + height );
-
- newWindow = NewCWindow( 0L, &wBounds, "\pSuper Snapshot!", false, kWindowFullZoomGrowDocumentProc,
- (WindowPtr)-1L, true, 0L );
- // The refcon of the windows are going to be used to store the PixMapHandle
- // from a screen capture. 0 means no associated PixMapHandle while non-zero
- // means the value is a handle to a PixMap. A windows refcon should always be
- // a value in this program
- SetWRefCon(newWindow, 0L);
- return newWindow;
- }
-
- void disposeWindow(WindowPtr dieWindow)
- {
- PixMapHandle pixHandle;
-
- if (dieWindow == NULL || !IsValidWindowPtr(dieWindow))
- return;
-
- // Free up the baseAddr pointer field, the PixMap itself,
- // and the window
- pixHandle = (PixMapHandle)GetWRefCon(dieWindow);
- if (pixHandle != nil) {
- LockPixels(pixHandle);
- DisposePtr((*pixHandle)->baseAddr);
- DisposeCTable((*pixHandle)->pmTable);
- // set the color table to nil since this was a "custom"
- // pixmap, otherwise DisposePixMap will not deallocate the memory
- (*pixHandle)->pmTable = nil;
- UnlockPixels(pixHandle);
- DisposePixMap(pixHandle);
- }
- DisposeWindow(dieWindow);
- }
-
- void calculateSystemBounds()
- {
- BitMap bitMap;
-
- // Get the resolution of the screen, save it in a global Rectangle and
- // use the info to calculate the min/max window size
-
- GetQDGlobalsScreenBits(&bitMap);
-
- SetRect( &gBounds, 0, 0, bitMap.bounds.right, bitMap.bounds.bottom);
- SetRect(&gMinWindowSize, bitMap.bounds.right / 4, bitMap.bounds.bottom / 4, bitMap.bounds.right, bitMap.bounds.bottom);
- }
-
- PixMapHandle createScreenPixMap()
- {
- GDHandle mainDevice;
- CTabHandle cTable;
- short depth;
- Ptr offBaseAddr; /* Pointer to the off-screen pixel image */
- short bytesPerRow;
- PixMapHandle pixHandle = nil;
-
- pixHandle = NewPixMap();
-
- /* Get a handle to the main device. */
- mainDevice = GetMainDevice();
-
- /* Store its current pixel depth. */
- depth = (**(**mainDevice).gdPMap).pixelSize;
-
- /* Make an identical copy of its pixmap's colortable. */
- cTable = (**(**mainDevice).gdPMap).pmTable;
- HandToHand( &(Handle)cTable );
-
- // Get Resolution of screen
- calculateSystemBounds();
-
- // Fill in a few of the PixMap's fields...
- // NewPixMap() is good for default initialization, simply modify
- // the new PixMap
- (*pixHandle)->pmTable = cTable;
- (*pixHandle)->bounds = gBounds;
- (*pixHandle)->pixelSize = depth;
- bytesPerRow = ((gBounds.right - gBounds.left) * depth) / 8;
- offBaseAddr = NewPtr((unsigned long) bytesPerRow * (gBounds.bottom - gBounds.top));
- (*pixHandle)->baseAddr = offBaseAddr; // Point to image
- (*pixHandle)->rowBytes = bytesPerRow | 0x8000; // MSB set for PixMap
-
- LockPixels(pixHandle);
-
- CopyBits( (BitMap *)*(**mainDevice).gdPMap, (BitMap *) *pixHandle,
- &(**(**mainDevice).gdPMap).bounds, &(*pixHandle)->bounds, srcCopy, 0l );
-
- UnlockPixels(pixHandle);
-
- return pixHandle;
- }
-
- void drawImage(WindowPtr theWindow)
- {
- Rect tempRect1;
- PixMapHandle pixHandle = (PixMapHandle) GetWRefCon(theWindow);
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPortWindowPort(theWindow);
- if (theWindow == NULL || !IsValidWindowPtr(theWindow))
- return;
- if (pixHandle == NULL)
- return;
- else
- LockPixels(pixHandle);
- // Copy the offscreen image back onto the window.
-
- CopyBits( (BitMap *) *pixHandle,
- GetPortBitMapForCopyBits(GetWindowPort(theWindow)),
- &(*pixHandle)->bounds,
- GetPortBounds(GetWindowPort(theWindow),&tempRect1),
- srcCopy, 0L);
-
- UnlockPixels(pixHandle);
- SetPort(oldPort);
- }
-
- void saveToPICTFile(WindowPtr theWindow)
- {
- PicHandle picHandle;
- OSErr anErr = noErr;
- NavReplyRecord reply;
- NavDialogOptions dialogOptions;
- FSSpec documentFSSpec;
- OSType fileTypeToSave = 'PICT';
- OSType creatorType = 'ogle'; // PictureViewer
- AEKeyword theKeyword;
- DescType actualType;
- Size actualSize;
- Rect tempRect1;
- PixMapHandle pixHandle;
-
- // This is a very basic NavServices file-saving example
- // added logic for this program specifically
-
- if (theWindow == NULL || !IsValidWindowPtr(theWindow))
- return;
-
- pixHandle = (PixMapHandle) GetWRefCon(theWindow);
- LockPixels(pixHandle);
-
- SetPortWindowPort(theWindow);
-
- GetPortBounds(GetWindowPort(theWindow), &tempRect1);
- picHandle = OpenPicture(&tempRect1);
-
- CopyBits((BitMap*) *pixHandle, GetPortBitMapForCopyBits(GetWindowPort(theWindow)), &(*pixHandle)->bounds,
- &tempRect1, srcCopy, 0L);
-
- ClosePicture();
-
- anErr = NavGetDefaultDialogOptions(&dialogOptions);
- dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
-
- // Set default name for a saved snapshot
- PLstrcpy(dialogOptions.savedFileName, defaultName);
-
- anErr = NavPutFile( nil,
- &reply,
- &dialogOptions,
- nil,
- fileTypeToSave,
- creatorType,
- nil );
-
- if (anErr == noErr && reply.validRecord) {
- anErr = AEGetNthPtr(&(reply.selection), 1, typeFSS,
- &theKeyword, &actualType,
- &documentFSSpec, sizeof(documentFSSpec),
- &actualSize );
- if (anErr == noErr) {
- writePictToFile(&documentFSSpec, picHandle);
- }
- reply.translationNeeded = false;
- anErr = NavCompleteSave(&reply, kNavTranslateInPlace);
-
- NavDisposeReply(&reply);
- }
- KillPicture(picHandle);
- UnlockPixels(pixHandle);
- }
-
- void writePictToFile(FSSpec *fspec, PicHandle picHandle)
- {
- OSErr anErr = noErr;
- long inOutCount;
- short refNum;
- OSType fileTypeToSave = 'PICT';
- OSType creatorType = 'ogle'; // PictureViewer
- int count;
- unsigned char header[512];
-
- // Pict files have to have 512 bytes of "zero" data at the front.
- for (count = 0; count < 512; count++)
- header[count] = 0x00;
-
- anErr = FSpCreate(fspec, creatorType, fileTypeToSave, smSystemScript);
- if (anErr == dupFNErr) {
- anErr = FSpDelete(fspec); //delete file if already exists
- anErr = FSpCreate(fspec, creatorType, fileTypeToSave, smSystemScript);
- }
-
- // write the file
- FSpOpenDF(fspec, fsRdWrPerm, &refNum );
- inOutCount = 512;
- anErr = FSWrite(refNum, &inOutCount, header); // write the header
- if (anErr == noErr) {
- inOutCount = GetHandleSize((Handle)picHandle);
- anErr = FSWrite(refNum,&inOutCount,*picHandle);
- }
- FSClose( refNum );
- }
-
- void doTrickEventLoop()
- {
- EventRecord anEvent;
- WindowPtr evtWind = NULL;
-
- // Event loop while doing the "full screen" trick
-
- while (!gDone) {
- if (WaitNextEvent( everyEvent, &anEvent, 2, nil )) {
- if (anEvent.what == updateEvt) {
- evtWind = (WindowPtr)anEvent.message;
- SetPortWindowPort(evtWind);
-
- BeginUpdate(evtWind);
- drawImage(evtWind);
- EndUpdate(evtWind);
- }
- else if (anEvent.what == autoKey || anEvent.what == keyDown)
- handleKeyPress(&anEvent);
- else if (anEvent.what == kHighLevelEvent)
- AEProcessAppleEvent(&anEvent);
- }
- }
- gDone = false;
- }
- void doConfusion()
- {
- int menuBarHeight = GetMBarHeight();
- GDHandle mainDevice;
- PicHandle picHandle;
- FSSpec fspec;
- PixMapHandle pixHandle;
- WindowPtr theWindow;
- float oldScale = gScale;
- OSErr anErr = noErr;
- AEDesc desc;
- Ptr oldState = NULL;
- WindowPtr bigWindow;
- RgnHandle rgnHandle = NewRgn();
- Rect tempRect1;
-
- gScale = 1;
-
- mainDevice = GetMainDevice();
-
- pixHandle = createScreenPixMap();
- LockPixels(pixHandle);
-
- if (!onOSX()) {
- // used a window for debugging purposes
- theWindow = createWindow();
- SetPortWindowPort(theWindow);
- SetWRefCon(theWindow, (long) pixHandle);
- picHandle = OpenPicture(&gBounds);
- drawImage(theWindow);
- ClosePicture();
- //ShowWindow(theWindow);
-
- // write pict to file
- FSMakeFSSpec(0, 0, fileName, &fspec);
- writePictToFile(&fspec, picHandle);
-
- // set desktop pict :-)
- anErr = OHMakeAliasDescFromFSSpec(&fspec, &desc);
- if (anErr == noErr) {
- SetDesktopPict(&desc, 1);
- AEDisposeDesc(&desc);
- }
- KillPicture(picHandle);
- DisposeWindow(theWindow);
- gDone = true;
- }
- else {
- // since OS X does not use the Appearance manager for the desktop background
- // we will drop into full screen mode instead
- gDoingTrick = true;
- BeginFullScreen(&oldState, nil, 0, 0, &bigWindow, 0, fullScreenAllowEvents);
- SetWRefCon(bigWindow, (long)pixHandle);
- SetPortWindowPort(bigWindow);
-
- CopyBits( (BitMap *) *pixHandle,
- GetPortBitMapForCopyBits(GetWindowPort(bigWindow)),
- &(*pixHandle)->bounds,
- GetPortBounds(GetWindowPort(bigWindow),&tempRect1),
- srcCopy, 0L);
- QDFlushPortBuffer(GetWindowPort(bigWindow), GetPortVisibleRegion(GetWindowPort(bigWindow), rgnHandle));
-
- doTrickEventLoop();
- EndFullScreen(oldState, nil);
- gDoingTrick = false;
- }
-
- // clean up
- DisposePtr((*pixHandle)->baseAddr);
- DisposeCTable((*pixHandle)->pmTable);
- UnlockPixels(pixHandle);
- DisposePixMap(pixHandle);
- DisposeRgn(rgnHandle);
- gScale = oldScale;
- }
-
-
- void adjustMenus()
- {
- // Function simply recalculates menus based on app state
- // Apps should do better menu handling, this is quick and dirty :-)
-
- MenuHandle menuHandle = GetMenuHandle(SIZE_MENU);
- int counter;
-
- for (counter = 1; counter <= NUMBER_OF_SIZES; counter++)
- CheckMenuItem(menuHandle, counter, false);
-
- if (gScale == QUARTER_SIZE)
- CheckMenuItem(menuHandle, SIZE_QUARTER_SCALE, true);
- else if (gScale == HALF_SIZE)
- CheckMenuItem(menuHandle, SIZE_HALF_SCALE, true);
- else if (gScale == FULL_SIZE)
- CheckMenuItem(menuHandle, SIZE_FULL_SCALE, true);
-
- menuHandle = GetMenuHandle(onOSX() ? FILE_MENUX : FILE_MENU);
-
- for (counter = 2; counter <= NUMBER_OF_FILE_MENU_ITEMS; counter++)
- FrontWindow() != NULL ? EnableMenuItem(menuHandle, counter) : DisableMenuItem(menuHandle, counter);
- }
-
- void resizeWindow(WindowPtr theWindow)
- {
- PixMapHandle pixHandle;
- Rect originalLoc, newLoc;
- Boolean wasCollapsed;
- RgnHandle rgnHandle = NewRgn();
-
- // Resize the window....
- if (theWindow == NULL || !IsValidWindowPtr(theWindow))
- return;
-
- wasCollapsed = IsWindowCollapsed(theWindow);
-
- if (wasCollapsed) {
- HideWindow(theWindow);
- CollapseWindow(theWindow, false);
- }
-
- pixHandle = (PixMapHandle)GetWRefCon(theWindow);
- GetWindowBounds(theWindow, kWindowContentRgn, &originalLoc);
-
- SetRect( &newLoc,
- originalLoc.left, originalLoc.top,
- gBounds.right / gScale + originalLoc.left,
- gBounds.bottom / gScale + originalLoc.top);
- SetWindowBounds(theWindow, kWindowContentRgn, &newLoc);
- drawImage(theWindow);
- QDFlushPortBuffer( GetWindowPort(theWindow),
- GetPortVisibleRegion(GetWindowPort(theWindow), rgnHandle));
-
- if (wasCollapsed) {
- CollapseWindow(theWindow, wasCollapsed);
- ShowWindow(theWindow);
- }
- DisposeRgn(rgnHandle);
- }
-
- void handleMenuSelection(long result)
- {
- int menuID, menuItem;
- RgnHandle rgnHandle = NewRgn();
- DialogPtr theDialog = NULL;
- short itemHit;
- PixMapHandle pixHandle;
-
- menuID = HiWord(result);
- menuItem = LoWord(result);
- HiliteMenu(0);
-
- // File Menu
- if (menuID == FILE_MENU || menuID == FILE_MENUX) {
- if (menuItem == FILE_SAVE)
- saveToPICTFile(FrontWindow());
- else if (menuItem == FILE_QUIT)
- gDone = true;
- else if (menuItem == FILE_CLOSE) {
- if (gDoingTrick)
- gDone = true;
- else if (FrontWindow() != NULL)
- disposeWindow(FrontWindow());
- }
- else if (menuItem == FILE_NEW) {
- doNewSnapshot();
- }
- else if (menuItem == FILE_REFRESH) {
- if (FrontWindow() == NULL) {
- HiliteMenu(0);
- return;
- }
- pixHandle = (PixMapHandle)GetWRefCon(FrontWindow());
- DisposePtr((**pixHandle).baseAddr);
- DisposePixMap(pixHandle);
- pixHandle = createScreenPixMap();
- SetWRefCon(FrontWindow(), (long)pixHandle);
- drawImage(FrontWindow());
- QDFlushPortBuffer(GetWindowPort(FrontWindow()), GetPortVisibleRegion(GetWindowPort(FrontWindow()), rgnHandle));
- }
- }
- else if (menuID == ABOUT_MENU) { //about menu handling
- if (menuItem == ABOUT) {
- theDialog = GetNewDialog ( ABOUTDLG, nil, (WindowPtr)-1 );
- do {
- ModalDialog ( nil, &itemHit );
- } while( itemHit != ok ) ;
- DisposeDialog ( theDialog );
- }
- }
- else if (menuID == SIZE_MENU) { //size menu
- switch (menuItem) {
- case SIZE_QUARTER_SCALE:
- gScale = QUARTER_SIZE;
- break;
- case SIZE_HALF_SCALE:
- gScale = HALF_SIZE;
- break;
- case SIZE_FULL_SCALE:
- gScale = FULL_SIZE;
- break;
- }
- resizeWindow(FrontWindow());
- }
- else if (menuID == SPECIAL_MENU || menuID == SPECIAL_MENUX) { // "special" because depends on OS 9 or X
- switch (menuItem) {
- case SPECIAL_CONFUSING:
- doConfusion();
- break;
- }
- }
- adjustMenus();
- DisposeRgn(rgnHandle);
- }
-
- void handleKeyPress(EventRecord *event)
- {
- char key;
-
- key = event->message & charCodeMask;
-
- // just check to see if the command key is down, if so
- // process it as menu selection
- if ( event->modifiers & cmdKey )
- handleMenuSelection(MenuKey(key));
- }
-
- // Apple Event - "Quit" Handler
- pascal OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, unsigned long refIn)
- {
- #pragma unused (messagein,refIn,reply)
-
- // Do not call ExitToShell() in an AE Handler....
- gDone = true;
- return noErr;
- }
-
- void doDynamicResizing(WindowPtr theWindow)
- {
- Point currentLoc;
- Rect windowBounds;
- long time;
- int offsetX, offsetY;
- int windowWidth, windowHeight;
- RgnHandle rgnHandle = NewRgn();
- EventRecord anEvent;
-
- // I could not find any code that would handle dynamic resizing using the "classic"
- // or traditional event model....so I wrote my own implementation
- GetWindowBounds(theWindow, kWindowStructureRgn, &windowBounds);
- GetMouse(¤tLoc);
- LocalToGlobal(¤tLoc);
-
- // calculate where mouse is in relation to edge of the window
- offsetX = windowBounds.right - currentLoc.h;
- offsetY = windowBounds.bottom - currentLoc.v;
- time = TickCount();
- while (Button()) {
- GetMouse(¤tLoc);
- LocalToGlobal(¤tLoc);
- GetWindowBounds(theWindow, kWindowStructureRgn, &windowBounds);
- windowBounds.bottom = currentLoc.v + offsetX;
- windowBounds.right = currentLoc.h + offsetY;
- windowWidth = windowBounds.right - windowBounds.left;
- windowHeight = windowBounds.bottom - windowBounds.top;
-
- // Error check the window rectangle
- if (windowWidth < gMinWindowSize.left)
- windowBounds.right = windowBounds.left + gMinWindowSize.left;
- if (windowHeight < gMinWindowSize.top)
- windowBounds.bottom = windowBounds.top + gMinWindowSize.top;
- SetWindowBounds(theWindow, kWindowStructureRgn, &windowBounds);
- // Draws every "resizingDelay" miliseconds, can easily change the interval
- // I've set the interval to 0 for instantaneous drawing, but different apps may want to
- // change the delay (maybe the drawing is quite complex....) or change it during execution
- if (TickCount() - time >= resizingDelay) {
- drawImage(theWindow);
- QDFlushPortBuffer(GetWindowPort(theWindow), GetPortVisibleRegion(GetWindowPort(theWindow), rgnHandle));
- time = TickCount();
- }
- WaitNextEvent( everyEvent, &anEvent, 0, nil );
- processEvent(&anEvent);
- // User may have decided to quit or close the window
- if (gDone || !IsValidWindowPtr(theWindow))
- break;
- }
- DisposeRgn(rgnHandle);
- // Update the window when all is done
- PostEvent(updateEvt, (long)theWindow);
- }
-
- void processEvent(EventRecord *anEvent)
- {
- WindowPtr evtWind;
- short clickArea;
- Rect screenRect;
- RgnHandle rgnHandle = NewRgn();
-
- // Pretty standard event processing, save the couple checks for the
- // "trick" flag being set
- if (anEvent->what == mouseDown)
- {
- clickArea = FindWindow( anEvent->where, &evtWind );
-
- if (clickArea == inMenuBar)
- handleMenuSelection(MenuSelect(anEvent->where));
- else if (clickArea == inDrag)
- {
- GetRegionBounds(GetGrayRgn(), &screenRect);
- DragWindow( evtWind, anEvent->where, &screenRect );
- }
- else if (clickArea == inContent)
- {
- if (evtWind != FrontWindow())
- SelectWindow( evtWind );
- }
- else if (clickArea == inGoAway) {
- if (TrackGoAway( evtWind , anEvent->where )) {
- disposeWindow(evtWind);
- adjustMenus();
- }
- }
- else if (clickArea == inGrow) {
- doDynamicResizing(evtWind);
- }
- else if (clickArea == inZoomIn || clickArea == inZoomOut) {
- if (TrackBox (evtWind, anEvent->where, clickArea == inZoomOut ? inZoomOut : inZoomIn)) {
- ZoomWindow (evtWind, clickArea == inZoomOut ? inZoomOut : inZoomIn, true);
- drawImage(evtWind);
- QDFlushPortBuffer(GetWindowPort(evtWind), GetPortVisibleRegion(GetWindowPort(evtWind), rgnHandle));
- }
- }
- }
- else if (anEvent->what == updateEvt)
- {
- evtWind = (WindowPtr)anEvent->message;
- SetPortWindowPort(evtWind);
-
- BeginUpdate(evtWind);
- drawImage(evtWind);
- EndUpdate(evtWind);
- }
- else if (anEvent->what == autoKey || anEvent->what == keyDown)
- handleKeyPress(anEvent);
- else if (anEvent->what == kHighLevelEvent)
- AEProcessAppleEvent(anEvent);
-
- DisposeRgn(rgnHandle);
- }
-
- void doEventLoop()
- {
- EventRecord anEvent;
-
- while (!gDone)
- if (WaitNextEvent( everyEvent, &anEvent, 10, nil))
- processEvent(&anEvent);
- }
-